
//--------------------------------------------------------------------------------------
// Texture samplers
//--------------------------------------------------------------------------------------
Texture2D g_MainTexture			: register(t0); 
Texture2D g_MainTextureAlpha	: register(t1); 

SamplerState SamplerPointClamp
{
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Clamp;
    AddressV = Clamp;
};

//--------------------------------------------------------------------------------------
// Constant Buffers
//--------------------------------------------------------------------------------------
shared cbuffer cbVSPF : register(cb0) // VS PER FRAME
{
	float4x4	g_mView;
	float4x4	g_mViewProjection;			// View * Projection matrix
	float4		g_LightDiffuse;              // Light's diffuse color  
	float4		g_vEye; 

	float		g_FogStart;
	float		g_FogEnd;

	float		g_fTime;
};

shared cbuffer cbPSPF : register(cb0) // PS PER FRAME
{
	float4		g_FogColor;					 // Fog
};

shared cbuffer cbVSPO : register(cb1) // VS PER OBJECT
{      
	float4x4	g_mWorld;					// World matrix for object
	float4		g_lGloballight;
};

shared cbuffer cbPSPO : register(cb1) // PS PER OBJECT
{

};
//--------------------------------------------------------------------------------------
// Vertex shader output structure
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 Position     : POSITION; // vertex position 
    float2 TextureUV    : TEXCOORD0;// vertex texture coords 
	float2 Light		: TEXCOORD1;// skylight
	float4 Diffuse		: COLOR0; //Color
};


//--------------------------------------------------------------------------------------
// Pixel shader output structure
//--------------------------------------------------------------------------------------
struct VS_OUTPUT
{
    float4 Position     : SV_POSITION; // vertex position 
    float4 Diffuse      : COLOR0;      // vertex diffuse color (note that COLOR0 is clamped from 0..1)
    float2 TextureUV    : TEXCOORD0;   // vertex texture coords 
	float  Fog			: TEXCOORD1;   // fog value
	float4 Light	    : TEXCOORD2;
};


//--------------------------------------------------------------------------------------
// This shader computes standard transform and lighting
//--------------------------------------------------------------------------------------
VS_OUTPUT RenderSceneVS( VS_INPUT input )
{
    VS_OUTPUT Output;
    //float3 vNormalWorldSpace;
	
	float4 depth;
	depth = mul(input.Position, g_mWorld);
	depth = mul(depth, g_mView);

	Output.Fog = saturate((g_FogEnd - length(depth)) / (g_FogEnd - g_FogStart));
    
    // Transform the position from object space to homogeneous projection space
	Output.Position = mul( input.Position, g_mWorld );
    Output.Position = mul( Output.Position, g_mViewProjection );
    
    // Transform the normal from object space to world space    
    //vNormalWorldSpace = input.Normal;//normalize(mul(input.Normal, (float3x3)g_mWorld)); // normal (world space)

    // Calc diffuse color 
	float3 light = (input.Light.x) * (g_LightDiffuse.xyz);//clamp((input.skyLight) * (g_LightDiffuse.xyz), 0.005f, 5.0f);
	float3 lerpvalue = 1.0f - input.Light.y;
	float3 torch = lerp(float3(1.0f, 1.0f, 1.0f), float3(2.0f, 1.0f, 0.0f),lerpvalue * lerpvalue) * input.Light.y;

    Output.Light = float4((light + torch), 1.0);
	Output.Diffuse = input.Diffuse;

							//g_MaterialDiffuseColor * g_LightDiffuse * max(0,dot(vNormalWorldSpace, g_vLightDir)) + 
							//g_MaterialAmbientColor;

    Output.Diffuse.a = 1.0f; 
    
    // Just copy the texture coordinate through
    Output.TextureUV = input.TextureUV; 
    
    return Output;      
}

VS_OUTPUT RenderSceneEntityVS( VS_INPUT input )
{
    VS_OUTPUT Output;
    //float3 vNormalWorldSpace;
	
	float4 depth;
	depth = mul(input.Position, g_mWorld);
	depth = mul(depth, g_mView);

	Output.Fog = saturate((g_FogEnd - length(depth)) / (g_FogEnd - g_FogStart));
    
    // Transform the position from object space to homogeneous projection space
	Output.Position = mul( input.Position, g_mWorld );
    Output.Position = mul( Output.Position, g_mViewProjection );
    
    // Transform the normal from object space to world space    
    //vNormalWorldSpace = input.Normal;//normalize(mul(input.Normal, (float3x3)g_mWorld)); // normal (world space)

    // Calc diffuse color 
	float3 light = (g_lGloballight.x) * (g_LightDiffuse.xyz);//clamp((input.skyLight) * (g_LightDiffuse.xyz), 0.005f, 5.0f);
	float3 lerpvalue = 1.0f - g_lGloballight.y;
	float3 torch = lerp(float3(1.0f, 1.0f, 1.0f), float3(2.0f, 1.0f, 0.0f),lerpvalue * lerpvalue) * g_lGloballight.y;

    Output.Light = float4((light + torch), 1.0);
	Output.Diffuse = input.Diffuse;

							//g_MaterialDiffuseColor * g_LightDiffuse * max(0,dot(vNormalWorldSpace, g_vLightDir)) + 
							//g_MaterialAmbientColor;

    Output.Diffuse.a = 1.0f; 
    
    // Just copy the texture coordinate through
    Output.TextureUV = input.TextureUV; 
    
    return Output;      
}

VS_OUTPUT RenderSceneAlphaVS( VS_INPUT input )
{
    VS_OUTPUT Output;
    //float3 vNormalWorldSpace;
	
	float3 depth;
	depth = mul(input.Position, g_mView).xyz;
	
	Output.Fog = saturate((g_FogEnd - length(depth)) / (g_FogEnd - g_FogStart));
    
    // Transform the position from object space to homogeneous projection space
	Output.Position = mul( input.Position, g_mWorld );
    Output.Position = mul( Output.Position, g_mViewProjection );
    
    // Transform the normal from object space to world space    
    //vNormalWorldSpace = input.Normal;//normalize(mul(input.Normal, (float3x3)g_mWorld)); // normal (world space)

    // Calc diffuse color 
	float3 light = (input.Light.x) * (g_LightDiffuse.xyz);//clamp((input.skyLight) * (g_LightDiffuse.xyz), 0.005f, 5.0f);
	float3 lerpvalue = 1.0f - input.Light.y;
	float3 torch = lerp(float3(1.0f, 1.0f, 1.0f), float3(2.0f, 0.5f, 0.0f),lerpvalue * lerpvalue) * input.Light.y;

    Output.Light = float4((light + torch), 1.0);
	Output.Diffuse = input.Diffuse;

							//g_MaterialDiffuseColor * g_LightDiffuse * max(0,dot(vNormalWorldSpace, g_vLightDir)) + 
							//g_MaterialAmbientColor;

    Output.Diffuse.a = 1.0f; 
    
    // Just copy the texture coordinate through
    Output.TextureUV = float2(input.TextureUV.x + g_fTime % (0.0625 * 2), input.TextureUV.y); 

    return Output;      
}

//--------------------------------------------------------------------------------------
// This shader outputs the pixel's color by modulating the texture's
// color with diffuse material color
//--------------------------------------------------------------------------------------
float4 RenderScenePS( VS_OUTPUT In ) : SV_TARGET
{ 
    // Lookup mesh texture and modulate it with diffuse
	float4 color = g_MainTexture.Sample(SamplerPointClamp, In.TextureUV );
	if (color.a < 0.5) discard;

	float4 fogColor = g_FogColor;//float4( 0.176f, 0.196f, 0.667f, 1.0f);

    float4 colordif = g_MainTextureAlpha.Sample(SamplerPointClamp, In.TextureUV );
		if (colordif.a > 0.5)
			color *= In.Diffuse;

	float4 textureColor = In.Light * color;

    return In.Fog * textureColor + (1.0 - In.Fog) * fogColor;
}

//--------------------------------------------------------------------------------------
// This shader outputs the pixel's color by modulating the texture's
// color with diffuse material color
//--------------------------------------------------------------------------------------
float4 RenderSceneAlphaPS( VS_OUTPUT In ) : SV_TARGET
{ 
	float4 color = g_MainTexture.Sample(SamplerPointClamp, In.TextureUV );

	float4 fogColor = g_FogColor;

    float4 colordif = g_MainTextureAlpha.Sample(SamplerPointClamp, In.TextureUV );
		if (colordif.a > 0.5)
			color *= In.Diffuse;

	float4 textureColor = In.Light * color;

    return In.Fog * textureColor + (1.0 - In.Fog) * fogColor;
}


BlendState NoAlphaBlend
{
    BlendEnable[0] = FALSE;
	AlphaToCoverageEnable = FALSE;

    SrcBlend = SRC_ALPHA;
    DestBlend = INV_SRC_ALPHA;
};

BlendState AlphaBlend
{
    BlendEnable[0] = TRUE;

    SrcBlend = SRC_ALPHA;
    DestBlend = INV_SRC_ALPHA;
	
    BlendOp = ADD;
    SrcBlendAlpha = ZERO;
    DestBlendAlpha = ZERO;
    BlendOpAlpha = ADD;
    RenderTargetWriteMask[0] = 0x0F;
	
};


technique11 RenderBlock
{
    pass Solid
    {
        SetVertexShader(CompileShader(vs_4_0, RenderSceneVS()));
        SetHullShader(NULL);
        SetDomainShader(NULL);
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, RenderScenePS()));

		SetBlendState( NoAlphaBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}

technique11 RenderBlockAlpha
{
    pass Solid
    {
        SetVertexShader(CompileShader(vs_4_0, RenderSceneAlphaVS()));
        SetHullShader(NULL);
        SetDomainShader(NULL);
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, RenderSceneAlphaPS()));

		SetBlendState( AlphaBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}